package app.controller;

import app.core.Client;
import app.core.model.IMessage;
import app.core.model.impl.Message;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.ScrollEvent;

import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class MainController implements Initializable {
    /**
     * 发送按钮
     */
    @FXML
    private Button send;

    /**
     * 聊天显示 - 文本域
     */
    @FXML
    private TextArea chatArea;

    /**
     * 输入区域 - 文本域
     */
    @FXML
    private TextArea inputArea;

    /**
     * 用户名 - 输入框
     */
    @FXML
    private TextField userName;

    /**
     * 提示区
     */
    @FXML
    private Label tips;

    /**
     * 在线列表
     */
    @FXML
    private ListView<String> userList;

    /**
     * 退出按钮
     */
    @FXML
    private Button exitApp;

    /**
     * 时间格式转换器
     */
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 客户端 - 用于发送网络请求
     */
    private Client client;

    /**
     * 本次连接的唯一id
     */
    private String token;

    /**
     * 记录 id -> 用户名 的映射关系
     */
    private Map<String,String> users = new HashMap<>();

    /**
     * 记录需要私聊的用户id
     */
    private String sendTo;

    /**
     * UI界面-发送消息的方法
     */
    public void sendMessage(){
        String text = inputArea.getText();
        if (text == null){
            return;
        }
        inputArea.setText("");
        if (sendTo != null){
            client.send(text,sendTo);

        }else {
            client.sendAll(text);
        }
    }

    /**
     * 初始化
     * @param location
     * @param resources
     */
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        //设置聊天显示区域不可编辑
        chatArea.setEditable(false);
        //设置自动换行
        chatArea.setWrapText(true);
        //连接客户端
        client = new Client("127.0.0.1", 13668);
        if (!client.isLink()){
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setContentText("连接服务器失败!");
            alert.showAndWait();
            System.exit(0);
        }
        //处理服务器响应的数据
        client.accept(this::deal);
        //点击发送按钮，发送消息
        send.setOnMouseClicked(event -> {
            sendMessage();
        });
        //点击退出按钮，结束程序
        exitApp.setOnMouseClicked(event -> {
            System.exit(0);
        });
        //按下ctrl+回车 发送消息
        inputArea.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER && event.isControlDown()){
                sendMessage();
            }
        });
        //监听用户改名 - 输入框失去焦点时
        userName.focusedProperty().addListener(e->{
            if (!userName.isFocused()){
                client.setName(userName.getText());
            }
        });
        //用户在线列表被点击时
        userList.setOnMouseClicked(event -> {
            String selectedItem = userList.getSelectionModel().getSelectedItem();
            if (sendTo != null && users.get(sendTo).equals(selectedItem)){
                sendTo = null;
                userList.getSelectionModel().clearSelection();
            }else {
                for (Map.Entry<String, String> entry : users.entrySet()) {
                    String k = entry.getKey();
                    String v = entry.getValue();
                    if (v.equals(selectedItem)) {
                        sendTo = k;
                        break;
                    }
                }
            }
            String temp = "当前消息将发送给:" + (sendTo==null?"所有人":users.get(sendTo));
            tips.setText(temp);
        });
    }

    /**
     * 处理消息
     * @param data 数据
     */
    private void deal(Message data) {
        switch (data.getType()){
            case ALL:
            case ORDINARY:
                chatArea.appendText(buildMessage(data));
                chatArea.setScrollTop(Double.MAX_VALUE);
                break;
            case FAIL:
                error(data);
                break;
            case LINK:
                initUserList(data);
                break;
            default:
        }
    }

    /**
     * 弹窗显示错误信息
     * @param data
     */
    private void error(Message data) {
        Platform.runLater(()->{
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setContentText(data.getMessage());
            alert.showAndWait();
        });
    }

    /**
     * UI界面-修改昵称
     * @param name
     */
    public void changeName(String name){
        client.setName(name);
        userName.setText(name);
    }

    /**
     * 初始化在线用户列表
     * @param data
     */
    private void initUserList(Message data) {
        List<String> messages = data.getMessages();
        String t = messages.get(0);
        String n = messages.get(1);
        if (this.token == null){
            token = t;
        }
        if(t.equals(this.token)){
            changeName(n);
        }
        users.clear();
        for(int i=2;i<messages.size();i+=2){
            users.put(messages.get(i),messages.get(i+1));
        }
        //更新UI界面
        Platform.runLater(()->{
            userList.setItems(FXCollections.observableList(new ArrayList<>(users.values())));
        });
    }

    /**
     * 构建聊天显示区的一条数据
     * @param data
     * @return
     */
    private String buildMessage(Message data){
        StringBuilder builder = new StringBuilder();
        Date date = new Date();
        date.setTime(Long.parseLong(data.getData(IMessage.TIME)));
        String time = this.format.format(date);
        builder.append("[");
        builder.append(time);
        builder.append("] ");
        builder.append(data.getData(IMessage.HEAD));
        builder.append("\n");
        builder.append(Optional.ofNullable(data.getMessage()).orElse(""));
        builder.append("\n");
        return builder.toString();
    }
}
